using System;
using System.Collections.Generic;
using Gj.Galaxy.Logic;
using SimpleJSON;
using Unity.Mathematics;
using UnityEngine;
using Random = System.Random;

namespace Gj
{
    public static class FixedTools
    {
        public static bool isFixed = true;
        public static int Multiply(float a, float b)
        {
            return isFixed ? (new FixedFloat(a) * new FixedFloat(b)).ToInt() : (int)(a * b);
        }

        public static int Divide(float a, float b)
        {
            return isFixed ? (new FixedFloat(a) / new FixedFloat(b)).ToInt() : (int)(a / b);
        }

        public static int AddPercent(int value, int change)
        {
            return isFixed ? (new FixedFloat(value) * new FixedFloat(100 + change) / new FixedFloat(100)).ToInt() : value * (100 + change) / 100;
        }


        public static int SubtractPercent(int value, int change)
        {
            return isFixed ? (new FixedFloat(value) * new FixedFloat(100 - change) / new FixedFloat(100)).ToInt() : value * (100 - change) / 100;
        }

        public static int Percent(int value, int change)
        {
            return isFixed ? (new FixedFloat(value) * new FixedFloat(change) / new FixedFloat(100)).ToInt() : value * change / 100;
        }

        public static int GetIndex(int rv, int[] ls)
        {
            int v = 0;
            for (int i = 0; i < ls.Length; i++)
            {
                v += ls[i];
                if (rv < v) return i;
            }

            return ls.Length - 1;
        }

        public static int RandomIndex(Random r, int length)
        {
            return GetIndex(r.Next(0, 99), length);
        }

        public static int GetIndex(int rv, int length)
        {
            return isFixed ? (new FixedFloat(rv) * new FixedFloat(length) / new FixedFloat(100)).ToFloor() : (int)math.floor(rv * length / 100.0f);
        }
    }
    [System.Serializable]
    public struct FixedFloat
    {
        private long rawValue;
        private const int PRECISION = 1000;
    
        public FixedFloat(float value)
        {
            rawValue = (long)(value * PRECISION);
        }
    
        public static FixedFloat operator + (FixedFloat a, FixedFloat b)
        {
            return new FixedFloat { rawValue = a.rawValue + b.rawValue };
        }
    
        public static FixedFloat operator - (FixedFloat a, FixedFloat b)
        {
            return new FixedFloat { rawValue = a.rawValue - b.rawValue };
        }
    
        public static FixedFloat operator * (FixedFloat a, FixedFloat b)
        {
            return new FixedFloat { rawValue = a.rawValue * b.rawValue / PRECISION };
        }

        public static FixedFloat operator / (FixedFloat a, FixedFloat b)
        {
            return new FixedFloat { rawValue = a.rawValue * PRECISION / b.rawValue };
        }
    
        public float ToFloat()
        {
            return (float)rawValue / PRECISION;
        }
    
        public int ToInt()
        {
            return ToFloor();
        }
    
        public int ToFloor()
        {
            return (int)math.floor(ToFloat());
        }
    
        public int ToCeil()
        {
            return (int)math.ceil(ToFloat());
        }
    
        public int ToRound()
        {
            return (int)math.round(ToFloat());
        }
    }

// 确定性向量
    [System.Serializable]
    public struct FixedVector3
    {
        public FixedFloat x;
        public FixedFloat y;
        public FixedFloat z;
    
        public FixedVector3(float x, float y, float z)
        {
            this.x = new FixedFloat(x);
            this.y = new FixedFloat(y);
            this.z = new FixedFloat(z);
        }
    
        public static FixedVector3 operator +(FixedVector3 a, FixedVector3 b)
        {
            return new FixedVector3
            {
                x = a.x + b.x,
                y = a.y + b.y,
                z = a.z + b.z
            };
        }
    
        public Vector3 ToVector3()
        {
            return new Vector3(x.ToFloat(), y.ToFloat(), z.ToFloat());
        }
    }
}